/**
 * elancom Corporation copy right 2012 - 2015  
 *   
 * $Header: https://192.168.1.224/svn/elancom/product/elancom-platform/trunk/src/main/java/com/elancom/framework/commons/json/serializer/FieldSerializer.java 1034 2012-07-02 03:09:12Z lanzhouxue $
 * $Id: FieldSerializer.java 1034 2012-07-02 03:09:12Z lanzhouxue $
 * $Author: lanzhouxue $
 * $Date: 2012-07-02 11:09:12 +0800 (Mon, 02 Jul 2012) $
 * $Revision: 1034 $
 */
package com.elancom.framework.commons.json.serializer;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

import com.elancom.framework.commons.json.annotation.JSONField;
import com.elancom.framework.commons.json.util.FieldInfo;

/**
 * @author elancom
 */
public abstract class FieldSerializer implements Comparable<FieldSerializer> {

	protected final FieldInfo fieldInfo;
	private final String double_quoted_fieldPrefix;
	private final String single_quoted_fieldPrefix;
	private final String un_quoted_fieldPrefix;
	private boolean writeNull = false;

	public FieldSerializer(FieldInfo fieldInfo) {
		super();
		this.fieldInfo = fieldInfo;
		fieldInfo.setAccessible(true);

		double_quoted_fieldPrefix = '"' + fieldInfo.getName() + "\":";

		single_quoted_fieldPrefix = '\'' + fieldInfo.getName() + "\':";

		un_quoted_fieldPrefix = fieldInfo.getName() + ":";

		final JSONField annotation = fieldInfo.getAnnotation(JSONField.class);
		if (annotation != null) {
			for (final SerializerFeature feature : annotation.serialzeFeatures()) {
				if (feature == SerializerFeature.WriteMapNullValue) {
					writeNull = true;
				}
			}
		}
	}

	public boolean isWriteNull() {
		return writeNull;
	}

	public Field getField() {
		return fieldInfo.getField();
	}

	public String getName() {
		return fieldInfo.getName();
	}

	public Method getMethod() {
		return fieldInfo.getMethod();
	}

	public void writePrefix(JSONSerializer serializer) throws IOException {
		final SerializeWriter out = serializer.getWriter();

		if (serializer.isEnabled(SerializerFeature.QuoteFieldNames)) {
			if (serializer.isEnabled(SerializerFeature.UseSingleQuotes)) {
				out.write(single_quoted_fieldPrefix);
			} else {
				out.write(double_quoted_fieldPrefix);
			}
		} else {
			out.write(un_quoted_fieldPrefix);
		}
	}

	@Override
	public int compareTo(FieldSerializer o) {
		return getName().compareTo(o.getName());
	}

	public Object getPropertyValue(Object object) throws Exception {
		return fieldInfo.get(object);
	}

	public abstract void writeProperty(JSONSerializer serializer, Object propertyValue) throws Exception;

}
